package game.controller;

import javafx.geometry.Bounds;

import java.util.ArrayList;
import java.util.List;

import static game.basic.GameBase.*;
import static game.controller.GameObject.currentMap;
import static game.main.GameApp.player;

public class CollisionChecker {

    //检查实体与图块之间的碰撞
    public void checkTile(Entity entity, int currentMap) {//检测与地图的碰撞
        int entityLeftWorldX = entity.worldX + entity.solidAreaX;
        int entityRightWorldX = entity.worldX + entity.solidAreaX + entity.solidAreaWidth;
        int entityTopWorldY = entity.worldY + entity.solidAreaY;
        int entityBottomWorldY = entity.worldY + entity.solidAreaY + entity.solidAreaHeight - 1;

        int entityLeftX = entityLeftWorldX / tileSize;
        int entityRightX = entityRightWorldX / tileSize;
        int entityTopY = entityTopWorldY / tileSize;
        int entityBottomY = entityBottomWorldY / tileSize;//这些就是地图中对应的坐标

        switch (entity.direction) {
            case upDir -> {
                entityTopY = (entityTopWorldY - entity.speed) / tileSize;
                entity.collisionOn = tile[mapTileNum[currentMap][entityTopY][entityLeftX]].collisionTile || tile[mapTileNum[currentMap][entityTopY][entityRightX]].collisionTile;
            }
            case downDir -> {
                entityBottomY = (entityBottomWorldY + entity.speed) / tileSize;
                entity.collisionOn = tile[mapTileNum[currentMap][entityBottomY][entityLeftX]].collisionTile || tile[mapTileNum[currentMap][entityBottomY][entityRightX]].collisionTile;
            }
            case leftDir -> {
                entityLeftX = (entityLeftWorldX - entity.speed) / tileSize;
                entity.collisionOn = tile[mapTileNum[currentMap][entityTopY][entityLeftX]].collisionTile || tile[mapTileNum[currentMap][entityBottomY][entityLeftX]].collisionTile;
            }
            case rightDir -> {
                entityRightX = (entityRightWorldX + entity.speed) / tileSize;
                entity.collisionOn = tile[mapTileNum[currentMap][entityTopY][entityRightX]].collisionTile || tile[mapTileNum[currentMap][entityBottomY][entityRightX]].collisionTile;
            }
        }
    }

    //检查实体与物品之间的碰撞
    public int checkObject(Entity entity, boolean player) {
        int index = 999;
        for (int i = 0; i < objArrLength; i++) {
            if (obj[currentMap][i] != null) {
                entity.solidAreaBoxX = entity.worldX + entity.solidAreaX;
                entity.solidAreaBoxY = entity.worldY + entity.solidAreaY;

                obj[currentMap][i].solidAreaBoxX = obj[currentMap][i].worldX + obj[currentMap][i].solidAreaX;
                obj[currentMap][i].solidAreaBoxY = obj[currentMap][i].worldY + obj[currentMap][i].solidAreaY;

                switch (entity.direction) {
                    case upDir -> entity.solidAreaBoxY -= entity.speed;
                    case downDir -> entity.solidAreaBoxY += entity.speed;
                    case leftDir -> entity.solidAreaBoxX -= entity.speed;
                    case rightDir -> entity.solidAreaBoxX += entity.speed;
                }

                if (entity.getRectangle().intersects(obj[currentMap][i].getRectangle())) {
                    if (obj[currentMap][i].collision) {
                        entity.collisionOn = true;
                    } else if (player) {
                        index = i;
                    }
                }
            }
        }
        return index;
    }

    //检查实体与实体之间的碰撞
    public int checkEntity(Entity entity, Entity[][] target) {
        int index = 999;
        for (int i = 0; i < target[0].length; i++) {
            if (target[currentMap][i] != null) {
                entity.solidAreaBoxX = entity.worldX + entity.solidAreaX;
                entity.solidAreaBoxY = entity.worldY + entity.solidAreaY;

                target[currentMap][i].solidAreaBoxX = target[currentMap][i].worldX + target[currentMap][i].solidAreaX;
                target[currentMap][i].solidAreaBoxY = target[currentMap][i].worldY + target[currentMap][i].solidAreaY;

                switch (entity.direction) {
                    case upDir -> entity.solidAreaBoxY -= entity.speed;
                    case downDir -> entity.solidAreaBoxY += entity.speed;
                    case leftDir -> entity.solidAreaBoxX -= entity.speed;
                    case rightDir -> entity.solidAreaBoxX += entity.speed;
                }

                if (entity.getRectangle().intersects(target[currentMap][i].getRectangle())) {
                    if (target[currentMap][i] != entity) {
                        entity.collisionOn = true;
                        index = i;
                    }
                }
            }
        }
        return index;
    }

    //检查实体与玩家之间的碰撞
    public boolean checkPlayer(Entity entity) {
        boolean contactPlayer = false;

        entity.solidAreaBoxX = entity.worldX + entity.solidAreaX;
        entity.solidAreaBoxY = entity.worldY + entity.solidAreaY;

        player.solidAreaBoxX = player.worldX + player.solidAreaX;
        player.solidAreaBoxY = player.worldY + player.solidAreaY;

        switch (entity.direction) {
            case upDir -> entity.solidAreaBoxY -= entity.speed;
            case downDir -> entity.solidAreaBoxY += entity.speed;
            case leftDir -> entity.solidAreaBoxX -= entity.speed;
            case rightDir -> entity.solidAreaBoxX += entity.speed;
        }

        if (entity.getRectangle().intersects(player.getRectangle())) {
            entity.collisionOn = true;
            contactPlayer = true;
        }
        return contactPlayer;
    }

    //检查范围攻击区域与实体之间的碰撞
    public List<Integer> attackEntityS(Bounds attackArea, Entity[][] target) {
        List<Integer> hitEntities = new ArrayList<>(); // 创建一个列表来存储被击中的实体编号
        for (int i = 0; i < target[0].length; i++) {
            if (target[currentMap][i] != null) {
                if (attackArea.intersects(target[currentMap][i].getRectangle())) {
                    hitEntities.add(i); // 将被击中的实体编号添加到列表中
                }
            }
        }
        return hitEntities;
    }
    //检查单体攻击区域与实体之间的碰撞
    public int attackEntity(Bounds attackArea, Entity[][] target) {
        for (int i = 0; i < target[0].length; i++) {
            if (target[currentMap][i] != null) {
                if (attackArea.intersects(target[currentMap][i].getRectangle())) {
                    return i;
                }
            }
        }
        return 999;
    }
}
